import tkinter as tk
import random
import time
import math

class SpaceInvaders:
    def __init__(self, master):
        self.master = master
        self.master.title("外星人入侵")
        self.master.geometry("800x600")
        self.master.resizable(False, False)
        self.master.config(bg="black")
        
        # 确保中文显示正常
        self.master.option_add("*Font", "SimHei 10")
        
        # 游戏设置
        self.width = 800
        self.height = 600
        self.ship_speed = 10
        self.bullet_speed = 15
        self.alien_speed = 2
        self.alien_bullet_speed = 8
        self.score = 0
        self.lives = 3
        self.game_over = False
        self.paused = False
        
        # 创建画布
        self.canvas = tk.Canvas(self.master, width=self.width, height=self.height, bg="black", highlightthickness=0)
        self.canvas.pack()
        
        # 加载游戏元素
        self.load_game_elements()
        
        # 绑定键盘事件
        self.master.bind("<KeyPress>", self.on_key_press)
        self.master.bind("<KeyRelease>", self.on_key_release)
        
        # 游戏循环
        self.game_loop()
    
    def load_game_elements(self):
        """加载游戏元素"""
        # 创建飞船
        self.ship = self.canvas.create_polygon(
            self.width/2-20, self.height-50,
            self.width/2, self.height-80,
            self.width/2+20, self.height-50,
            fill="white"
        )
        
        # 创建外星人
        self.aliens = []
        self.alien_bullets = []
        self.bullets = []
        self.explosions = []
        
        # 初始化外星人位置
        for i in range(5):
            for j in range(10):
                x = 100 + j * 60
                y = 100 + i * 50
                alien = self.canvas.create_oval(
                    x-15, y-15,
                    x+15, y+15,
                    fill="red"
                )
                self.aliens.append({
                    "id": alien,
                    "x": x,
                    "y": y,
                    "direction": 1  # 1 向右，-1 向左
                })
        
        # 创建记分牌和生命值
        self.score_text = self.canvas.create_text(50, 20, text="得分: 0", fill="white", font=("SimHei", 16))
        self.lives_text = self.canvas.create_text(750, 20, text="生命: 3", fill="white", font=("SimHei", 16))
        
        # 游戏说明
        self.instructions = self.canvas.create_text(
            self.width/2, 
            self.height-30, 
            text="使用左右箭头移动，空格键发射，P键暂停", 
            fill="gray", 
            font=("SimHei", 12)
        )
        
        # 按键状态
        self.keys = {"Left": False, "Right": False, "space": False}
    
    def on_key_press(self, event):
        """处理按键按下事件"""
        key = event.keysym
        if key in self.keys:
            self.keys[key] = True
        elif key == 'p' or key == 'P':
            self.paused = not self.paused
            if self.paused:
                self.canvas.create_text(
                    self.width/2, 
                    self.height/2, 
                    text="游戏暂停，按P继续", 
                    fill="white", 
                    font=("SimHei", 24),
                    tags="pause"
                )
            else:
                self.canvas.delete("pause")
    
    def on_key_release(self, event):
        """处理按键释放事件"""
        key = event.keysym
        if key in self.keys:
            self.keys[key] = False
    
    def move_ship(self):
        """移动飞船"""
        if self.keys["Left"] and self.get_ship_x() > 30:
            self.canvas.move(self.ship, -self.ship_speed, 0)
        if self.keys["Right"] and self.get_ship_x() < self.width - 30:
            self.canvas.move(self.ship, self.ship_speed, 0)
    
    def get_ship_x(self):
        """获取飞船的x坐标"""
        coords = self.canvas.coords(self.ship)
        return (coords[0] + coords[4]) / 2
    
    def get_ship_y(self):
        """获取飞船的y坐标"""
        coords = self.canvas.coords(self.ship)
        return coords[1]
    
    def fire_bullet(self):
        """发射子弹"""
        if not self.paused and not self.game_over and self.keys["space"]:
            # 限制子弹数量，避免过多
            if len(self.bullets) < 3:
                x = self.get_ship_x()
                y = self.get_ship_y()
                
                bullet = self.canvas.create_rectangle(
                    x-3, y-15,
                    x+3, y,
                    fill="white"
                )
                
                self.bullets.append({
                    "id": bullet,
                    "x": x,
                    "y": y
                })
    
    def move_bullets(self):
        """移动子弹"""
        # 移动玩家子弹
        bullets_to_remove = []
        for i, bullet in enumerate(self.bullets):
            self.canvas.move(bullet["id"], 0, -self.bullet_speed)
            bullet["y"] -= self.bullet_speed
            
            # 检查是否击中外星人
            hit_alien_index = self.check_alien_hit(bullet)
            if hit_alien_index is not None:
                self.explode_alien(hit_alien_index)
                bullets_to_remove.append(i)
                self.score += 10
                self.canvas.itemconfig(self.score_text, text=f"得分: {self.score}")
            # 检查是否超出边界
            elif bullet["y"] < 0:
                bullets_to_remove.append(i)
        
        # 移除击中或超出边界的子弹
        for i in sorted(bullets_to_remove, reverse=True):
            self.canvas.delete(self.bullets[i]["id"])
            del self.bullets[i]
    
    def check_alien_hit(self, bullet):
        """检查子弹是否击中外星人"""
        bullet_coords = self.canvas.coords(bullet["id"])
        for i, alien in enumerate(self.aliens):
            alien_coords = self.canvas.coords(alien["id"])
            
            # 检查子弹是否与外星人重叠
            if (bullet_coords[2] >= alien_coords[0] and bullet_coords[0] <= alien_coords[2] and
                bullet_coords[3] >= alien_coords[1] and bullet_coords[1] <= alien_coords[3]):
                return i
        return None
    
    def explode_alien(self, index):
        """外星人爆炸效果"""
        alien = self.aliens[index]
        x, y = alien["x"], alien["y"]
        
        # 创建爆炸效果
        explosion = self.canvas.create_oval(
            x-20, y-20,
            x+20, y+20,
            fill="yellow",
            outline="orange"
        )
        
        self.explosions.append({
            "id": explosion,
            "x": x,
            "y": y,
            "radius": 20,
            "time_left": 20  # 爆炸持续时间
        })
        
        # 删除外星人
        self.canvas.delete(alien["id"])
        del self.aliens[index]
    
    def move_aliens(self):
        """移动外星人"""
        if not self.aliens:  # 如果没有外星人了，游戏胜利
            self.game_over = True
            self.canvas.create_text(
                self.width/2, 
                self.height/2, 
                text="恭喜你获胜！得分: " + str(self.score), 
                fill="white", 
                font=("SimHei", 24)
            )
            return
        
        # 检查是否需要改变方向
        change_direction = False
        for alien in self.aliens:
            x = alien["x"]
            if x < 30 and alien["direction"] == -1:
                change_direction = True
                break
            elif x > self.width - 30 and alien["direction"] == 1:
                change_direction = True
                break
        
        # 移动外星人
        for alien in self.aliens:
            if change_direction:
                alien["direction"] *= -1
                self.canvas.move(alien["id"], 0, 30)
                alien["y"] += 30
            else:
                self.canvas.move(alien["id"], alien["direction"] * self.alien_speed, 0)
                alien["x"] += alien["direction"] * self.alien_speed
    
    def aliens_fire(self):
        """外星人发射子弹"""
        if not self.aliens or random.random() > 0.01:  # 1%的概率发射子弹
            return
        
        # 随机选择一个外星人发射子弹
        alien = random.choice(self.aliens)
        x, y = alien["x"], alien["y"]
        
        bullet = self.canvas.create_rectangle(
            x-3, y+15,
            x+3, y+30,
            fill="green"
        )
        
        self.alien_bullets.append({
            "id": bullet,
            "x": x,
            "y": y
        })
    
    def move_alien_bullets(self):
        """移动外星人子弹"""
        bullets_to_remove = []
        for i, bullet in enumerate(self.alien_bullets):
            self.canvas.move(bullet["id"], 0, self.alien_bullet_speed)
            bullet["y"] += self.alien_bullet_speed
            
            # 检查是否击中飞船
            if self.check_ship_hit(bullet):
                bullets_to_remove.append(i)
                self.hit_ship()
            # 检查是否超出边界
            elif bullet["y"] > self.height:
                bullets_to_remove.append(i)
        
        # 移除击中或超出边界的子弹
        for i in sorted(bullets_to_remove, reverse=True):
            self.canvas.delete(self.alien_bullets[i]["id"])
            del self.alien_bullets[i]
    
    def check_ship_hit(self, bullet):
        """检查外星人子弹是否击中飞船"""
        bullet_coords = self.canvas.coords(bullet["id"])
        ship_coords = self.canvas.coords(self.ship)
        
        # 检查子弹是否与飞船重叠
        if (bullet_coords[2] >= ship_coords[0] and bullet_coords[0] <= ship_coords[4] and
            bullet_coords[3] >= ship_coords[1] and bullet_coords[1] <= ship_coords[3]):
            return True
        return False
    
    def hit_ship(self):
        """飞船被击中"""
        self.lives -= 1
        self.canvas.itemconfig(self.lives_text, text=f"生命: {self.lives}")
        
        if self.lives <= 0:
            self.game_over = True
            self.canvas.create_text(
                self.width/2, 
                self.height/2, 
                text="游戏结束！得分: " + str(self.score), 
                fill="white", 
                font=("SimHei", 24)
            )
        else:
            # 飞船闪烁效果
            for i in range(5):
                self.canvas.itemconfig(self.ship, fill="red" if i % 2 == 0 else "white")
                self.master.update()
                time.sleep(0.1)
            self.canvas.itemconfig(self.ship, fill="white")
    
    def update_explosions(self):
        """更新爆炸效果"""
        explosions_to_remove = []
        for i, explosion in enumerate(self.explosions):
            explosion["time_left"] -= 1
            if explosion["time_left"] <= 0:
                explosions_to_remove.append(i)
            else:
                # 爆炸效果逐渐消失
                alpha = explosion["time_left"] / 20
                color = f"#{int(255*alpha):02x}{int(255*alpha):02x}{int(0*alpha):02x}"
                self.canvas.itemconfig(explosion["id"], fill=color, outline=color)
        
        # 移除完成的爆炸效果
        for i in sorted(explosions_to_remove, reverse=True):
            self.canvas.delete(self.explosions[i]["id"])
            del self.explosions[i]
    
    def check_game_over(self):
        """检查游戏是否结束"""
        if self.game_over:
            return
        
        # 检查外星人是否到达底部
        for alien in self.aliens:
            if alien["y"] > self.height - 100:
                self.game_over = True
                self.canvas.create_text(
                    self.width/2, 
                    self.height/2, 
                    text="游戏结束！得分: " + str(self.score), 
                    fill="white", 
                    font=("SimHei", 24)
                )
                break
    
    def game_loop(self):
        """游戏主循环"""
        if not self.paused and not self.game_over:
            self.move_ship()
            self.fire_bullet()
            self.move_bullets()
            self.move_aliens()
            self.aliens_fire()
            self.move_alien_bullets()
            self.update_explosions()
            self.check_game_over()
        
        self.master.after(30, self.game_loop)

if __name__ == "__main__":
    root = tk.Tk()
    game = SpaceInvaders(root)
    root.mainloop()